﻿using Microsoft.Win32;
using NPOI.SS.Formula.Functions;
using Org.BouncyCastle.Utilities.Net;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;

namespace Common.Tools
{
    /// <summary>
    /// 计算机信息助手类
    /// </summary>
    public class ComputerInfoHelper
    {
        /// <summary>
        /// 返回启动当前正在执行的进程的可执行文件的路径。 当路径不可用时返回 null 
        /// </summary>
        /// <returns></returns>
        public static string? ProcessPath()
        {
            return Environment.ProcessPath;
        }

        /// <summary>
        /// 获取当前平台标识符和版本号，例如：Microsoft Windows NT 10.0.19044.0
        /// </summary>
        /// <returns></returns>
        public static OperatingSystem GetOSVersion()
        {
            return Environment.OSVersion;
        }

        /// <summary>
        /// 获取与当前线程相关联的用户的用户名。
        /// </summary>
        /// <returns></returns>
        public static string GetUserName()
        {
            return Environment.UserName;
        }

        /// <summary>
        /// 获取与当前用户关联的网络域名
        /// </summary>
        /// <returns></returns>
        public static string GetUserDomainName()
        {
            return Environment.UserDomainName;
        }

        /// <summary>
        /// 获取计算机名
        /// </summary>
        /// <returns></returns>
        public static string GetMachineName()
        {
            return System.Environment.MachineName;

        }

        /// <summary>
        /// 获取Ip地址(IPV4)，此方法返回的数据中会包含虚拟网卡的地址 
        /// </summary>
        /// <param name="isOnlyActive">是否仅限活动状态的网卡</param>
        /// <param name="addressFamily">Ip地址的地址族,IPV4/IPV6</param>
        /// <returns></returns>
        public static List<string> GetIpAddress(bool isOnlyActive = true, AddressFamily  addressFamily = AddressFamily.InterNetwork)
        {
            List<NetworkInterface> networkInterfaceList = GetAllNetworkInterfaces(isOnlyActive);

            // 方法里面的注释不删除
            //Debug.WriteLine("Interface information for {0}.{1}     ",
            //    computerProperties.HostName, computerProperties.DomainName);
            if (networkInterfaceList.Count < 1)
            {
                Debug.WriteLine("  No network interfaces found.");
                return new List<string>();
            }
            var ipAddress = new List<string>();
            //Debug.WriteLine("  Number of interfaces .................... : {0}", nics.Length);
            foreach (NetworkInterface adapter in networkInterfaceList)
            {
                //Debug.WriteLine("");
                //Debug.WriteLine(adapter.Name + "," + adapter.Description);
                //Debug.WriteLine(string.Empty.PadLeft(adapter.Description.Length, '='));
                //Debug.WriteLine("  Interface type .......................... : {0}", adapter.NetworkInterfaceType);
                //Debug.Write("  Physical address ........................ : ");
                //PhysicalAddress address = adapter.GetPhysicalAddress();
                //byte[] bytes = address.GetAddressBytes();
                //for (int i = 0; i < bytes.Length; i++)
                //{
                //    // Display the physical address in hexadecimal.
                //    Debug.Write($"{bytes[i]:X2}");
                //    // Insert a hyphen after each byte, unless we are at the end of the 
                //    // address.
                //    if (i != bytes.Length - 1)
                //    {
                //        Debug.Write("-");
                //    }
                //}

                //Debug.WriteLine("");

                //Debug.WriteLine(address.ToString());                
                IPInterfaceProperties properties = adapter.GetIPProperties();                
                var unicastAddresses = properties.UnicastAddresses;

                foreach (var item in unicastAddresses)
                {
                    if(item.Address.AddressFamily == addressFamily)
                    {
                        string ip = item.Address.ToString();                        
                        if(!string.IsNullOrEmpty(ip) && !ipAddress.Contains(ip))
                        {
                            ipAddress.Add(ip);
                        }
                    }
                }
            }

            return ipAddress;
        }

        /// <summary>
        /// 获取Mac地址(IPV4)，此方法返回的数据中会包含虚拟网卡的地址 
        /// </summary>
        /// <param name="isOnlyActive">是否仅限活动状态的网卡</param>
        /// <param name="separator">Mac地址分割符，如：00-50-56-C0-00-08或00:50:56:C0:00:08</param>
        /// <param name="addressFamily">Ip地址的地址族,IPV4/IPV6</param>
        /// <returns></returns>
        public static List<string> GetMacAddress(bool isOnlyActive = true, string separator = "-", AddressFamily addressFamily = AddressFamily.InterNetwork)
        {
            List<NetworkInterface> networkInterfaceList = GetAllNetworkInterfaces(isOnlyActive);

            // 方法里面的注释不删除
            //Debug.WriteLine("Interface information for {0}.{1}     ",
            //    computerProperties.HostName, computerProperties.DomainName);
            if (networkInterfaceList.Count < 1)
            {
                Debug.WriteLine("  No network interfaces found.");
                return new List<string>();
            }
            var macAddress = new List<string>();
            //Debug.WriteLine("  Number of interfaces .................... : {0}", nics.Length);
            foreach (NetworkInterface adapter in networkInterfaceList)
            {
                //Debug.WriteLine("");
                //Debug.WriteLine(adapter.Name + "," + adapter.Description);
                //Debug.WriteLine(string.Empty.PadLeft(adapter.Description.Length, '='));
                //Debug.WriteLine("  Interface type .......................... : {0}", adapter.NetworkInterfaceType);
                //Debug.Write("  Physical address ........................ : ");
                //PhysicalAddress address = adapter.GetPhysicalAddress();
                //byte[] bytes = address.GetAddressBytes();
                //for (int i = 0; i < bytes.Length; i++)
                //{
                //    // Display the physical address in hexadecimal.
                //    Debug.Write($"{bytes[i]:X2}");
                //    // Insert a hyphen after each byte, unless we are at the end of the 
                //    // address.
                //    if (i != bytes.Length - 1)
                //    {
                //        Debug.Write("-");
                //    }
                //}

                //Debug.WriteLine("");

                //Debug.WriteLine(address.ToString());

                IPInterfaceProperties properties = adapter.GetIPProperties();
                var unicastAddresses = properties.UnicastAddresses;
                if (unicastAddresses.Any(temp => temp.Address.AddressFamily == addressFamily))
                {
                    var address = adapter.GetPhysicalAddress();
                    string mac = "";
                    if (string.IsNullOrEmpty(separator))
                    {
                        mac = address.ToString();
                    }
                    else
                    {
                        mac = string.Join(separator, address.GetAddressBytes().Select(p=> p.ToString("X2")));
                    }
                    if(!string.IsNullOrEmpty(mac) && !macAddress.Contains(mac))
                    {
                        macAddress.Add(mac);
                    }
                }
            }

            return macAddress;
        }

        /// <summary>
        /// 提供有关本地计算机的网络连接的信息
        /// 可通过该类的属性：获取动态主机配置协议 (DHCP) 范围名、获取在其中注册本地计算机的域、获取本地计算机的主机名、获取本地计算机的网络基本输入/输出系统 (NetBIOS) 节点类型
        /// </summary>
        /// <returns></returns>
        public static IPGlobalProperties GetIPGlobalProperties()
        {
            IPGlobalProperties computerProperties = IPGlobalProperties.GetIPGlobalProperties();
            return computerProperties;

        }


        /// <summary>
        /// 本地计算机上网络接口（也称为适配器）的配置和统计信息;
        /// <see cref="GetAllNetworkInterfaces"/> 返回一个数组，该数组包含本地计算机上的每个网络接口的 <see cref="NetworkInterface"/> 实例
        /// </summary>
        /// <param name="isOnlyActive">是否仅限活动状态的网卡</param>
        /// <returns></returns>
        public static List<NetworkInterface> GetAllNetworkInterfaces(bool isOnlyActive = true)
        {
            List<NetworkInterface> res = new List<NetworkInterface>();
            NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
            if(nics != null)
            {
                List<NetworkInterface> networkInterfaceList = nics.Where(c =>
                    c.NetworkInterfaceType != NetworkInterfaceType.Loopback).ToList();
                if (isOnlyActive == true)
                {
                    networkInterfaceList = networkInterfaceList.Where(p => p.OperationalStatus == OperationalStatus.Up).ToList();
                }
                res = networkInterfaceList;
            }
            return res;
        }
    }
}
